<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
            "http://www.w3.org/TR/REC-html40/loose.dtd">
<HTML>
<HEAD>



<META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<META name="GENERATOR" content="hevea 1.08">
<LINK rel="stylesheet" type="text/css" href="embroot.css">
<TITLE>
Communication via Queues
</TITLE>
</HEAD>
<BODY >
<A HREF="embroot020.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A>
<A HREF="embroot016.html"><IMG SRC ="contents_motif.gif" ALT="Up"></A>
<A HREF="embroot022.html"><IMG SRC ="next_motif.gif" ALT="Next"></A>
<HR>

<H2 CLASS="section"><A NAME="htoc38">5.5</A>&nbsp;&nbsp;Communication via Queues</H2><UL>
<LI><A HREF="embroot021.html#toc19">From-ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> to Tcl</A>
<LI><A HREF="embroot021.html#toc20">To-ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> from Tcl</A>
</UL>

<A NAME="tclembedqueues"></A>
<A NAME="ecqueueconnect"></A>
The most flexible way of passing data between ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> and Tcl is
via the I/O facilities of the two languages,
ie. via ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> queue streams which can be connected to Tcl channels.<BR>
<BR>
Currently, a communication channel between ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> and Tcl is created
from Tcl, which appears as an ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> queue in ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP>, and a channel
in Tcl. The queue has a symbolic name and a stream number in ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP>,
and has a channel name in Tcl. Facilities are provided to interconvert
between these names. <BR>
<BR>
Queues pass data between ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> and Tcl in one direction: either from
ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> to Tcl (from-ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP>), or from Tcl to ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP>
(to-ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP>). Queues are created with the direction specified. The
queues should be viewed as communication channels: data is written to the
queue, and it only becomes available to the other side when the queue is
flushed. This is done by calling the predicate <A HREF="../bips/kernel/iostream/flush-1.html"><B>flush/1</B></A><A NAME="@default87"></A> on the
ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side, and by invoking <B>ec_flush</B> on the Tcl side. The flush
also has the effect of briefly transferring control to the other side to
allow handlers to handle the data (see
section&nbsp;<A HREF="embroot022.html#embtclhandlers">5.6</A>)<SUP><A NAME="text1" HREF="embroot016.html#note1">1</A></SUP>
<DL CLASS="description" COMPACT=compact><DT CLASS="dt-description">
<A NAME="@default88"></A><B>ec_queue_create <I>eclipse_stream_name mode ?command? ?event?</I></B><DD CLASS="dd-description"><BR>
Creates a queue between Tcl and ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP>. On
 the Tcl side, a Tcl channel is created. On the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side, the 
 queue would be given the symbolic name <I>eclipse_stream_name</I>. 
 The <I>mode</I> argument indicates the direction of the queue, and
 can either be fromec or toec<SUP><A NAME="text2" HREF="embroot016.html#note2">2</A></SUP>.
 The procedure returns a channel identifier for use in commands
 like <B>puts</B>, <B>read</B>, <B>ec_read_exdr</B>,
 <B>ec_write_exdr</B> or <B>close</B>. The optional arguments <I>command</I> and <I>event</I> specifies the data handler for the
 queue: <I>command</I> is the name
 of the Tcl
 procedure for handling the data, with its user defined arguments. 
 <I>event</I> is the name of the event that will be
 raised on the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side.
 As a handler can only be defined for one side,
 either <I>event</I> or <I>command</I> should be undefined
 (<CODE>{}</CODE>). <BR>
<BR>
<DT CLASS="dt-description"><A NAME="@default89"></A><B>ec_queue_close <I>eclipse_stream_name</I></B><DD CLASS="dd-description"><BR>
	Closes the queue with the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> name of <I>	ec_stream_name</I>. <BR>
<BR>
<DT CLASS="dt-description"><A NAME="@default90"></A><B>ec_stream_nr <I>eclipse_stream_name</I></B><DD CLASS="dd-description"><BR>
This command returns the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> stream number given a
 symbolic stream name (this is the same operation that the
 ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> built-in
 <A HREF="../bips/kernel/iostream/get_stream-2.html"><B>get_stream/2</B></A><A NAME="@default91"></A>
 performs). <BR>
<BR>
<DT CLASS="dt-description"><A NAME="@default92"></A><B>ec_streamname_to_streamnum <I>eclipse_stream_name</I></B><DD CLASS="dd-description"><BR>
	This is an alias for <I>ec_stream_nr</I> for compatibility purposes.<BR>
<BR>
<DT CLASS="dt-description"><A NAME="@default93"></A><B>ec_streamname_to_channel <I>eclipse_stream_name</I></B><DD CLASS="dd-description"><BR>
	Returns the Tcl channel name for the queue with the
	symbolic name <I>eclipse_name</I>. <BR>
<BR>
<DT CLASS="dt-description"><A NAME="@default94"></A><B>ec_streamnum_to_channel <I>eclipse_stream_number</I></B><DD CLASS="dd-description"><BR>
	Returns the Tcl channel name for the queue with the
	ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> stream number <I>eclipse_stream_number</I>. <BR>
<BR>
<DT CLASS="dt-description"><A NAME="@default95"></A><B>ec_async_queue_create <I>eclipse_stream_name mode
	?command? ?event?</I></B><DD CLASS="dd-description"><BR>
	This is provided mainly for compatibility with the Tcl remote
	interface. The command is an alias for <B>ec_queue_create</B> in the
	embedding interface. Certain uses of the queues in the embedding
	interface cannot be duplicated using the synchronous queues of the
	remote interface. Instead, asynchronous queues are needed (see
	chapter&nbsp;<A HREF="embroot026.html#chapremote">6</A> for more details). This command is
	provided to allow the same code to be used for both interfaces. 
	Note that it is possible to use the asynchronous queues of the remote
	interface in ways that are incompatible with the embedding interface.</DL>
<A NAME="toc19"></A>
<H3 CLASS="subsection"><A NAME="htoc39">5.5.1</A>&nbsp;&nbsp;From-ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> to Tcl</H3>
To create a queue from ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> to Tcl, use <B>ec_queue_create</B> with
the <I>mode</I> argument set to <B>fromec</B>, e.g.

<BLOCKQUOTE CLASS="quote"><PRE CLASS="verbatim">
Tcl:            set my_in_channel [ec_queue_create my_out_queue fromec]
</PRE></BLOCKQUOTE>
Once the queue is created, it
can be used, e.g. by writing into it with ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP>'s
<A HREF="../bips/kernel/ioterm/write-2.html"><B>write/2</B></A><A NAME="@default96"></A> builtin,
and reading using Tcl's <B>read</B> command:
<BLOCKQUOTE CLASS="quote"><PRE CLASS="verbatim">
ECLiPSe:        write(my_out_queue, hello),
                flush(my_out_queue).

Tcl:            set result [read $my_in_channel 5]
</PRE></BLOCKQUOTE>
The disadvantage of using these low-level primitives is that
for reading one must know exactly how many bytes to read.
It is therefore recommended to use the EXDR (ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> external data
representation, see section <A HREF="embroot024.html#secexdrtcl">5.8</A>) format for communication.
This allows to send and receive structured and typed data.
The primitives to do that are
<A HREF="../bips/kernel/ioterm/write_exdr-2.html"><B>write_exdr/2</B></A><A NAME="@default97"></A>
on the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side and
ec_read_exdr (section <A HREF="embroot024.html#ecreadexdr">5.8</A>) on the Tcl side:
<BLOCKQUOTE CLASS="quote"><PRE CLASS="verbatim">
ECLiPSe:        write_exdr(my_out_queue, foo(bar,3)),
                flush(my_out_queue).
         
Tcl:            set result [ec_read_exdr $my_in_channel]
</PRE></BLOCKQUOTE>
In the example, the Tcl result will be the list <TT>{foo bar 3}</TT>.
For details about the mapping see section <A HREF="embroot024.html#secexdrtcl">5.8</A>.<BR>
<BR>
<A NAME="toc20"></A>
<H3 CLASS="subsection"><A NAME="htoc40">5.5.2</A>&nbsp;&nbsp;To-ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> from Tcl</H3>
To create a queue from Tcl to ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> to Tcl, use <B>ec_queue_create</B> with
the <I>mode</I> argument set to <B>toec</B>, e.g.
<BLOCKQUOTE CLASS="quote"><PRE CLASS="verbatim">
Tcl:            set my_out_channel [ec_queue_create my_in_queue toec]
</PRE></BLOCKQUOTE>
Now the queue can be used, e.g. by writing into it with Tcl's <B>puts</B>
command and by reading using ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP>'s
<A HREF="../bips/kernel/iochar/read_string-4.html"><B>read_string/4</B></A><A NAME="@default98"></A>
builtin:
<BLOCKQUOTE CLASS="quote"><PRE CLASS="verbatim">
Tcl:            puts $my_out_channel hello
                ec_flush [ec_streamname_to_streamnum my_in_queue] 5

ECLiPSe:        read_string(my_in_queue, "", 5, Result).
</PRE></BLOCKQUOTE>
The disadvantage of using these low-level primitives is that
for reading one must know exactly how many bytes to read, or define
a delimiter character.
It is therefore recommended to use the EXDR (ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> external data
representation, see section <A HREF="embroot024.html#secexdrtcl">5.8</A>) format for communication.
This allows to send and receive structured and typed data.
The primitives to do that are
ec_read_exdr (section <A HREF="embroot024.html#ecwriteexdr">5.8</A>) on the Tcl side and
<A HREF="../bips/kernel/ioterm/read_exdr-2.html"><B>read_exdr/2</B></A><A NAME="@default99"></A>
on the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side:
<BLOCKQUOTE CLASS="quote"><PRE CLASS="verbatim">
Tcl:            ec_write_exdr $my_out_channel {foo bar 3} (SI)
                ec_flush [ec_streamname_to_streamnum my_in_queue]

ECLiPSe:        read_exdr(my_in_queue, Result).
</PRE></BLOCKQUOTE>
In the example, the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> result will be the term <TT>foo("bar",3)</TT>.
For details about the mapping see section <A HREF="embroot024.html#secexdrtcl">5.8</A>.<BR>
<BR>
<HR>
<A HREF="embroot020.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A>
<A HREF="embroot016.html"><IMG SRC ="contents_motif.gif" ALT="Up"></A>
<A HREF="embroot022.html"><IMG SRC ="next_motif.gif" ALT="Next"></A>
</BODY>
</HTML>
